<?php
function a(&$a, $k){
	return $a[$k];
}

function hook($result){
	global $hook;
	$d_backtrace=debug_backtrace();
	$backtrace=is_array($d_backtrace[1])?$d_backtrace[1]:$d_backtrace;
	$functions=@$hook[$backtrace['function']];
	$args=$backtrace['args'];
	if(is_array($functions)){
		ksort($functions);
		foreach($functions as $function)
			if($function&&function_exists($function))
				$result=$function($result,$args);
	}
	return $result;
}

if(!function_exists('generate_link')){
	function generate_link($string=''){
		global $_s;
		return hook(@$_s['base_url'].'/?'.$str=str_replace('//','/',$string));
	}
}

function tf_encode($name){# encode tag filename
	return hook(str_replace('/','%2F',base64_encode($name)));
}

function tf_decode($name){# decode tag filename
	return hook(base64_decode(str_replace('%2F','/',$name)));
}

function upload_files() {
	global $_s, $_v;
	$upload_dir = "files/";
	if(isset($_FILES['usrfile']['name']) && @trim($_FILES['usrfile']['name'])!="") {
		for ($i=0; $i<sizeof($_FILES['usrfile']['name']); $i++){
			if(@trim($_FILES['usrfile']['name'][$i]!="")) {
				if (!move_uploaded_file($_FILES['usrfile']['tmp_name'][$i], $upload_dir.rawurlencode($_FILES['usrfile']['name'][$i]))) {
					copy($_FILES['usrfile']['tmp_name'][$i], rawurlencode($_FILES['usrfile']['name'][$i]));
					@$allfil .= $_FILES['usrfile']['name'][$i]."\n";
				} else @$allfil .= $_FILES['usrfile']['name'][$i]."\n";
			}
		}
	return hook($_FILES['usrfile']['name'][$i]);
	}
	else return hook(FALSE);
}

function clean_str($str){
	return hook(trim(str_replace(array("\n","\r","\t",'\\','/','.','%','&',':','<','>','"','\''),'',$str)));
}

function dir2array($patch){
	$d = dir($patch);
	while (false !== ($entry = $d->read()))
		if ($entry!='readme.txt'&&$entry!='readme.txt~'&&$entry!='.'&&$entry!='..'&&$entry!='.svn')
			$entries[] = $entry;
	$d->close();
	return hook($entries);
}

function getapts() {
	global $_s;
	return hook(dir2array($_s['posts_dir']));
}

function ct($tag){//Кеширует отдельный тег
	if(!$tag)return hook(FALSE);
	global $_s;
	$posts=dir2array($_s['tags_dir']);
	$tag_cache_array = array();
	foreach($posts as $post){
		$file=$_s['tags_dir'].'/'.$post;
		if(is_file($file)){
			$f=file_get_contents($file);
			$tags=explode(',',$f);
			if(($tags && in_array($tag,$tags))||$f==$tag)$tag_cache_array[]=$post;
		}
	}
	$tag_cache=implode(',',$tag_cache_array);
	$file=$_s['tags_cache'].'/'.tf_encode($tag);
	fsave($file,'w',$tag_cache);
	return hook(TRUE);
}

function cache_tags($str=''){//Функция для массового/одиночного кеширования тегов
	global $_s;
	$tag=is_array($str)?$str:(strstr($str,',')?explode(',',$str):$str);
	if(is_array($tag)){
		foreach($tag as $t)ct($t);
	}
	elseif($tag!='')ct($tag);
	else {
		$posts=dir2array($_s['tags_dir']);
		$a_tags=array();
		foreach($posts as $post)if(is_numeric($post)&&is_file($_s['tags_dir'].'/'.$post))$a_tags = array_merge($a_tags,explode(',',file_get_contents($_s['tags_dir'].'/'.$post)));
		foreach(array_unique($a_tags) as $tag)ct($tag);
	}
	return hook(true);
}

function getbytag($tag){
	global $_s;
	$file=$_s['tags_cache'].'/'.tf_encode($tag);
	if(file_exists($file)){
		$posts=explode(',',file_get_contents($file));
	}
	else $posts = false;
	return hook($posts);
}

function admenu($idpo) {
	global $post, $_l;
	if (ADMIN) {
		$post['admenu'] = "";
		$post['admenu'] = '<a href="'.generate_link('action=edit_post&p='.$idpo).'">'.$_l['edit'].'</a>';
		$post['admenu'] .= ' <a href="'.generate_link('action=del_post&p='.$idpo).'" onclick="if(!confirm(\'Вы уверены?\')) return false;">'.$_l['delete'].'</a>';
		$_l['admenu']=&$post['admenu'];
	}
	return hook($post['admenu']);
}

function br(&$post) {
	global $_s;
	if(@$_s['br'])$post['text'] = str_replace("\n", "<br>", $post['text']);
	return hook($post);
}

function string_to_tags($string){
	global $_l,$_v;
	$tags=explode(',',$string);
	$string=$_l['tags'].' ';
	$last_tag=array_pop($tags);
	if(count($tags))foreach($tags as $tag)$string.='<a href="'.generate_link('t='.$tag).'">'.$tag.'</a>, ';
	return hook($string.'<a href="'.generate_link('t='.$last_tag).'">'.$last_tag.'</a>');
}

function post_info($p){
	global $_s, $_l,$_v;
	if (!is_numeric($p) || !file_exists($_s['posts_dir'].'/'.$p)||(@gbuffer($p,"close") && !ADMIN))return hook(FALSE);
	list($post['title'], $post['text']) = explode("\n", file_get_contents($_s['posts_dir'].'/'.$p), 2);
	$post['id'] = $p;
	@$post['date'] = date($_s['dateformat'], $p + ($_s['time_offset'] * 3600));
	if (!file_exists($_s['comments_dir'].'/'.$p)) $post['c_count'] = 0;
	else $post['c_count'] = sizeof(file($_s['comments_dir'].'/'.$p));
	if (file_exists($_s['tags_dir'].'/'.$p) && filesize($_s['tags_dir'].'/'.$p)>0)$post['tags']=((@$_v['action']=='edit_post')?file_get_contents($_s['tags_dir'].'/'.$p):string_to_tags(file_get_contents($_s['tags_dir'].'/'.$p)));
	else $post['tags'] = '';
	return hook($post);
}

function redirect($u) {
	global $_l;
	$u=preg_replace('/#(.*)$/i','',$u);
	echo hook('<meta http-equiv="refresh" content="4;url='.$u.'"><center><b>'.$_l['wait_4_sec'].'</b><br>[ <a href="'.$u.'">'.$_l['dont_wait'].'</a> ]</center>');
	return true;
}


function fsave($fle,$mod,$txt) {
	if($fh = fopen($fle, $mod)){
		flock($fh, LOCK_EX);
		fwrite($fh, $txt);
		flock($fh, LOCK_UN);
		fclose($fh);
		@chmod($fle, 0777);
		return hook(true);
	}
	else return hook(false);
}

function sbuffer($id, $var, $val='') {
	$rec = 'data/inf/'.$id.'_'.$var;
	return hook(fsave($rec,'w+',$val));
}

function gbuffer($id, $var=FALSE) {
	$rec = 'data/inf/'.$id.'_'.$var;
	if(file_exists($rec))return hook(file_get_contents($rec));
	else return hook(FALSE);
}

function dbuffer($id, $var=FALSE){
	if($var){
		$rec = 'data/inf/'.$id.'_'.$var;
		if(file_exists($rec))return hook(unlink($rec));
	}
	else foreach (dir2array('data/inf') as $var)if(preg_match('/^'.$id.'_(.*)/i',$var))	dbuffer($id,$var);
}

function chekers () {
	global $_v, $p;
	sbuffer($_v['p'], "close", @$_v['closep']);
	sbuffer($_v['p'], "comments", @$_v['nocomm']);
	sbuffer($_v['p'], "nomail", @$_v['nomailc']);
	sbuffer($_v['p'], "maillist", @$_v['mailo']);
	sbuffer($_v['p'], "hidecomm", @$_v['comhidden']);
	sbuffer($_v['p'], "norss", @$_v['norss']);
	return hook(TRUE);
}

function bbcode($msg) {
 	return hook(preg_replace(
 		'/(\[url\])([!\s]+)(\[\/url\])/isU',
 		'<a href="\\2">\\2</a>',
 		str_replace(
 			array("[u]","[i]","[b]","[sub]","[sup]","[/u]","[/i]","[/b]","[/sub]","[/sup]"),
 			array("<u>","<em>","<strong>","<sub>","<sup>","</u>","</em>","</strong>","</sub>","</sup>"),
 			$msg
 		)
 	));
}

function swiki($msg) {
	if(@trim($msg))	return hook(preg_replace(
		array('/------/isU','/\[\[(.*)\]\]/isU','/vv(.*)vv/isU','/\^\^(.*)\^\^/isU','/<<(.*)>>/isU','/=====(.*)=====/isU','/====(.*)====/isU','/===(.*)===/isU','/==(.*)==/isU',"{(?<!:)//(\S.*?\S|\S)(?<!:)//}s",'/__(.*)__/isU','/--(.*)--/isU','/\*\*(.*)\*\*/isU'),
		array('<hr>','<a href="\\1">\\1</a>','<sub>\\1</sub>','<sup>\\1</sup>','&laquo;\\1&raquo;','<h4>\\1</h4>','<h3>\\1</h3>','<h2>\\1</h2>','<h1>\\1</h1>','<i>\\1</i>','<u>\\1</u>','<s>\\1</s>','<strong>\\1</strong>'),
		$msg)
	);
}

function nae_exit($text='',$exit=''){
	global $_i, $_t;
	extract($_t, EXTR_REFS);
	echo $text;
	include $_i['tpl_patch'].'/footer.html';
	exit(hook($exit));
}


# Pages
function nae_page($pagg){
	global $_v, $_s, $_l, $_i, $_t;
	extract($_t, EXTR_REFS);
	$pagg=trim($pagg);
	if (file_exists($_s['pages_dir'].'/'.$pagg) && eregi("^([A-Za-z0-9А])", $pagg)) {
		ob_start();
		include $_s['pages_dir'].'/'.$pagg;
		$pg=ob_get_contents();
		ob_end_clean();
		if(ADMIN) $pg.='<div class="admenu"><a href="'.generate_link('action=edit_pag&pg='.$pagg).'">'.$_l['edit'].'</a> <a href="'.generate_link('action=del_pag&pg='.$pagg).'">'.$_l['delete'].'</a></div>';
	}
	elseif(ADMIN)$pg=nae_new_page($pagg);
	else $pg=$_l['not_found'];
	return hook($pg);
}

function nae_new_page($pagg=''){
	global $_v, $_s, $_i, $_l, $_t, $post;
	extract($_t, EXTR_REFS);
	$_v['action']="new_pag";
	$post['title']=$pagg;
	$_v['p']=trim($_v['pg']);
	ob_start();
	include $_i['tpl_patch'].'/post_form.html';
	$return = ob_get_contents();
	ob_end_clean();
	return hook($return);
}

function nae_edit_page($name){
	if(!$name)return hook(FALSE);
	global $_v, $_s, $_i, $_l, $_t, $post;
	extract($_t, EXTR_REFS);
	$name = trim($name);
	$post['text']=htmlspecialchars(@file_get_contents($_s['pages_dir'].'/'.$name));
	$_v['action']="new_pag";
	$post['title']=$name;
	ob_start();
	include $_i['tpl_patch'].'/post_form.html';
	$return = ob_get_contents();
	ob_end_clean();
	return hook($return);
}

function nae_save_page($name,$content){
	if(!$name)return hook(FALSE);
	global $_s;
	fsave($_s['pages_dir'].'/'.$name,"w+",$content);
	return hook($name);
}

function nae_delete_page($name){
	global $_s;
	return hook (@unlink($_s['pages_dir'].'/'.$_v['pg']));
}

#Posts
function nae_posts_list($tag = '', $skip = 0){
	global $_s, $_l, $_v;
	$posts = array();
	$tag=clean_str($tag);
	if($tag) $posts = getbytag($tag);
	else $posts = getapts();
	if(!$posts&&$tag) return hook(nae_exit($_l['tag_no_exists']));
	if(!$posts) return hook(FALSE);
	@rsort($posts);
	foreach($posts as $n=>$post)if(gbuffer($post,'close')&&!ADMIN)unset($posts[$n]);
	$pages = sizeof($posts) / $_s['ppp'];
	$skip = (isset($skip) && is_numeric($skip) ? $skip : 0);
	$dmpcmtsl=$_l['comments'];
	if (sizeof($posts) > $_s['ppp']) $posts = array_slice($posts, $skip, $_s['ppp']);
	$return = '<div class="posts_list">';
	if($posts)foreach ($posts as $p)$return.=nae_post($p,true);
	$return .= '</div>';
	if ( $pages > 1 ){
		$pages_link = array();
		for ( $i = 0; $i < $pages; $i++ )$pages_link[] = "<a href=\"" . ( generate_link(($tag?'t='.$tag.'&':'').'skip=' . $i * $_s['ppp']) ) . "\">" . ( $skip == $i * $_s['ppp'] ? "<strong>" . ( $i + 1 ) . "</strong>" : $i + 1 ) . "</a>";
	}
	return hook($return);
}

function nae_post($p,$ct=FALSE){
	if(!$p)return hook($_l['not_found']);
	global $_v, $_s, $_i, $_l, $_t, $post;
	extract($_t, EXTR_REFS);
	$post = post_info($p);
	if(gbuffer($p,"close") && !ADMIN)return hook($_l['not_found']);
	else {
		$moretitle = "";
		if(gbuffer($post['id'],"close"))$moretitle .= $_l['close_title'];
		br($post);
		if(gbuffer($post['id'],"comments")){$_s['comments']=0; $_l['comments']=$_l['freeze'];}
		$post['admenu']=admenu($post['id']);
		if($ct && (preg_match("#(.*)<cut text=\"(.*)\">#sU", $post['text'], $cut) || preg_match("#(.*)<cut>#sU", $post['text'], $cut))){
			if(isset($cut[2])) {
			$post['text'] = $cut[1].'<a href="'.generate_link('p='.$post['id']).'">'.$cut[2].'</a>';
			} else {
			$post['text'] = $cut[1].'<a href="'.generate_link('p='.$post['id']).'">'.$_l['more'].'</a>';
			}
		}
		$post['text']=preg_replace('#</?cut( text="([^"]*)")?>#sU','',$post['text']);
		$post['title'] = (@trim($post['title']) ? $post['title'] : $_l['notitle']);
		ob_start();
		include $_i['tpl_patch'].'/post.html';
		$return = ob_get_contents();
		ob_end_clean();
	}
	return hook($return);
}

function nae_new_post($p=false){
	global $_v, $_s, $_i, $_l, $_t, $post;
	extract($_t, EXTR_REFS);
	ob_start();
	include $_i['tpl_patch'].'/post_form.html';
	$return = ob_get_contents();
	ob_end_clean();
	return hook($return);
}

function nae_edit_post($p){
	if(!$p)return hook(FALSE);
	global $_v, $_s, $_i, $_l, $_t, $post;
	extract($_t, EXTR_REFS);
	$post = post_info($p);
	$post['text'] = str_replace(array("\r", "\n"), array("", "\r"), $post['text']);
	$post['text'] = str_replace("\r", "\n", $post['text']);
	$post['text'] = htmlspecialchars($post['text'], ENT_QUOTES);
	return hook(nae_new_post($p));
}

function nae_save_post($p,$title,$text,$tags){
	if(!$p)return hook(FALSE);
	global $_s;
	if($_s['wiki']) $text=swiki($text);
	fsave($_s['posts_dir'].'/'.$p,"w+",$title."\n".$text);
	fsave($_s['comments_dir'].'/'.$p,"a+","");
	@chmod($_s['data_dir'].'/inf/'.$p, 0777);
	$tags_o = array();
	if(file_exists($_s['tags_dir'].'/'.$p))$tags_o=split(',',file_get_contents($_s['tags_dir'].'/'.$p));
	if($tags){
		$tags_a=array_map('clean_str',split(',',$tags));
		$tags=implode(',',$tags_a);
		fsave($_s['tags_dir'].'/'.$p,'w',$tags);
		cache_tags(array_unique(@array_merge($tags_a,$tags_o)));
	}
	chekers();
	upload_files();
	return hook($p);
}

function nae_delete_post($p){
	if(!$p)return hook(FALSE);
	global $_s;
	$files=gbuffer($p, 'files');
	if($files) foreach(array_map('trim',split("\n",$files)) as $file) unlink("files/".$file);
	dbuffer($p);
	chekers();
	@unlink($_s['comments_dir'].'/'.$p);
	if(file_exists($_s['tags_dir'].'/'.$p)){
		$tags=file_get_contents($_s['tags_dir'].'/'.$p);
		@unlink($_s['tags_dir'].'/'.$p);
		if(@$tags)cache_tags($tags);
	}
	return hook(unlink($_s['posts_dir'].'/'.$p));
}

# Comments
function nae_comments_list($p){
	if(!$p)return hook(FALSE);
	global $_v, $_s, $_i, $_l, $_t, $post;
	extract($_t, EXTR_REFS);
	if ($_s['comments']||ADMIN){
		$return = '<h3><a href="#comment" name="comment">Комментарии:</a></h3><ul id="comments_list">';
		$comments = @file($_s['comments_dir'].'/'.$p); $i=0;
		if($comments) foreach ($comments as $comment){$return .= nae_comment($comment,$p,$i);$i++;}
		ob_start();
		include $_i['tpl_patch'].'/comment_form.html';
		$return.= ob_get_contents().'</div>';
		ob_end_clean();
		return hook($return);
	}
	else return hook(false);
}

function nae_comment($comment,$p,$i){
	if(!$comment||!$p||!isset($i))return hook(FALSE);
	global $_v, $_s, $_i, $_l, $_t, $post;
	extract($_t, EXTR_REFS);
	$hidden='';
	if(@gbuffer($p,'comments'))$_s['comments']=0; $_l['comments']=$_l['freeze'];
	$cmnt = explode("¦¦", $comment);
	$cmnt = array_combine(array('nick','priv','ip','web','date','text','email'),$cmnt);
	if(ADMIN)$cmnt['del'] = '<a href="'.generate_link('action=del_comment&c='.$i.'&p='.$p).'" onclick="if(!confirm(\'Вы уверены?\')) return false;">удалить</a>';
	$cmnt['date'] = date($_s['comment_dateformat'], $cmnt['date']+($_s['time_offset']*3600));
	$cmnt['text'] = preg_replace("#\[(.*)\]#sU", "[<b>\\1</b>] ", $cmnt['text']);
	$hiddenmenu="";
	if(ADMIN) {
		if(@$cmnt['priv']==1) {
			$hidden=$_l['cmnt_hide'];
			$hiddenmenu='<a href="'.generate_link('action=unhide_comment&c='.$i.'&p='.$post['id']).'">'.$_l['cmnt_op'].'</a>';
		} else $hiddenmenu='<a href="'.generate_link('action=hide_comment&c='.$i.'&p='.$post['id']).'">'.$_l['cmnt_hi']."</a>";
	}
	if(@$cmnt['priv']==1 && !ADMIN && getenv("REMOTE_ADDR")!=$cmnt['ip']) {}#skip this comment
	else {
		if($cmnt['priv']==1)$hidden=$_l['cmnt_hide'];
		ob_start();
		if($cmnt['nick']==$_s['authorname']) include $_i['tpl_patch'].'/comment_a.html';
		else include $_i['tpl_patch'].'/comment.html';
		$return = ob_get_contents();
		ob_end_clean();
	}
	return hook($return);
}

function nae_comment_visible($p,$c,$h=0){
	if(!$p||!isset($c))return hook(FALSE);
	global $_s;
	$v = (int)(bool)$v;
	$cmnts = file($_s['comments_dir'].'/'.$p);
	$cmnt = explode('¦¦', $cmnts[$c]);
	$cmnt[1]=$h;
	$cmnts[$c]=implode('¦¦', $cmnt);
	return hook(fsave($_s['comments_dir'].'/'.$p,"w+",implode('', $cmnts)));
}

function nae_delete_comment($p,$c){
	if(!$p||!isset($c))return hook(FALSE);
	global $_s;
	$cmnts = file($_s['comments_dir'].'/'.$p);
	unset($cmnts[$c]);
	return hook(fsave($_s['comments_dir'].'/'.$p,"w+",implode("", $cmnts)));
}

function nae_new_comment($p,$time=''){
	if(!$p)return hook(FALSE);
	global $_v, $_s, $_l;
	$_v['nick']=trim(@$_v['nick'])?$_v['nick'] : $_l['anonymous'];
	$return='';
	if ($_s['comments'] && !gbuffer($p,"comments")) {
		if ($_v['nick']==$_s['authorname'] && !ADMIN) return hook($_l['ncikden']);
		else {
			if (trim(@$_v['text'])){
				if(gbuffer($_v['p'],"hidecomm") && !ADMIN)$_s['premoderation']=1;
				$privat = (((@$_s['allowhide'] && @$_v['privat'])||$_s['premoderation'])&& !ADMIN)?1:0;
				$text = str_replace('¦','',substr($_v['text'], 0, 4096));
				$nick = str_replace('¦','',substr(@$_v['nick'], 0, 24));
				$www = str_replace('¦','',strtolower(strip_tags(substr(@$_v['web'], 0, 45))));if(trim($www) && !strstr($www,"http")) $www="http://".$www;
				$email = htmlspecialchars(str_replace('¦','',substr(@$_v['email'],0,45)));

				if(!ADMIN) {
					$text = htmlspecialchars($text, ENT_QUOTES);
					$nick = strip_tags($nick);
				}
				
				$text = str_replace(array("\n",'¦'),array('<br>',''),$text);
				if(@$_s['bbcode']) $text=bbcode($text);
	
				$cmnt_date = $time?$time:(time()+($_s['time_offset']*3600));
				fsave($_s['comments_dir'].'/'.$_v['p'],'a+',$nick.'¦¦'.$privat.'¦¦'.getenv('REMOTE_ADDR').'¦¦'.$www.'¦¦'.$cmnt_date.'¦¦'.$text.'¦¦'.$email."\n");
				$cmntid=count(file($_s['comments_dir'].'/'.$_v['p']))-1;
		
				if(@$_s['premoderation']&&!ADMIN) $return .= '<p>'.$_l['cmnt_add_pre'].'</p>';
				$return.='<p>'.$_l['cmnt_add'].'</p>';

				if ($_s['email']!="" && !gbuffer($_v['p'],"nomail")) {
					$email=$email?$email:$_s['email'];
					@mail(
						$_s['email'],
						"Comment ".iconv($_s['encoding'],'koi8-r',$nick),
						str_replace('<br>',"\n",iconv($_s['encoding'],'koi8-r',$text))."\n\n".generate_link('p='.$_v['p'])."#comment-$cmntid\n",
						'Content-Type: text/plain; charset=koi8-r'."\nFrom: ".iconv($_s['encoding'],'koi8-r',$nick)."<$email>\r\n");
				}
			} else return hook($_l['cmnt_empty']);
		}
	}
}

function nae_ext_save($a){
	global $_s;
	$f=fopen($_s['data_dir'].'/ext.ini.php','w');
	$b=";<?php /*\n";
	foreach($a as $name => $status)
		if(preg_match('/^\w+[a-z0-9-_]*$/i',$name)&&$name!='edit_ext')
			$b.=$name.'='.$status."\n";
	$b.=';*/ ?>';
	return fsave($_s['data_dir'].'/ext.ini.php','w',$b);
}
